package com.rits.mysecrets.dao
import com.googlecode.mapperdao.utils._
import com.rits.mysecrets.model.User
import com.googlecode.mapperdao._
import org.springframework.transaction.PlatformTransactionManager

/**
 * dao for users.
 *
 * This is declared abstract and later on the missing dependencies are provided
 * by Daos.scala .
 *
 * @author kostantinos.kougios
 *
 * 15 Sep 2011
 */

abstract class UserDao extends TransactionalSurrogateIntIdCRUD[User] with SurrogateIntIdAll[User] {
	// by mixing in TransactionalIntIdCRUD[User], we add create(User), retrieve(id), update(User), delete(User) transactional methods.
	// by mixing IntIdAll[User] we add all:List[User with IntId] method

	protected val entity = UserEntity // entity field is needed by the traits

	// queries
	import Query._
	import queryDao._
	private val u = UserEntity

	/**
	 * returns the user by his email
	 */
	def byEmail(email: String) = query(
		select from u // u is an "alias" to UserEntity
			where u.email === email
	).headOption
	/**
	 * if email & password are correct, will return Some(User) else None
	 *
	 * @param email			user's email
	 * @param password		user's password
	 * @return				Some(User with IntId) or None
	 */
	def login(email: String, password: String) = query(
		select from u // u is an "alias" to UserEntity 
			where u.email === email
			and u.password === password
	).headOption
	/**
	 * all users except user
	 */
	def allBut(user: User) = all filterNot (user == _) // all method is provided by trait IntIdAll[User]
}

/**
 * the mapping for the User class. We map from a User class (which doesn't have an id) to
 * a User with IntId (since the database provides an autogenerated id)
 */
object UserEntity extends Entity[Int, SurrogateIntId, User] {
	val id = key("id") autogenerated (_.id) // the id is auto-generated and maps to column "id" and field _.id
	val name = column("name") to (_.name)
	val email = column("email") to (_.email)
	val password = column("password") to (_.password)

	def constructor(implicit m) = new User(name, email, password) with SurrogateIntId {
		val id: Int = UserEntity.id // when an entity is been loaded from the database, the auto-generated id is available
	}
}
